package com.njcb.ams.util;

import com.njcb.ams.support.exception.ExceptionUtil;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.StringConverter;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @author liuyanlong
 *
 */
public class AmsBeanUtils {
	private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
	
	static {
		//解决BeanUtils拷贝BigDecimal为null报错问题，现初始化为0
		BigDecimalConverter bd = new BigDecimalConverter(new BigDecimal(0));
		ConvertUtils.register(bd, java.math.BigDecimal.class);
		
		StringConverter sc = new StringConverter("");
		ConvertUtils.register(sc, java.lang.String.class);
	}

	public static void copyProperties(Object dest, Object orig) {
		try {
			mapperFactory.getMapperFacade().map(orig, dest);
		} catch (Exception e) {
			ExceptionUtil.throwAppException(e);
		}
	}
	
	public static String getProperty(Object bean, String name) {
		try {
			return BeanUtilsBean.getInstance().getProperty(bean, name);
		} catch (Exception e) {
			ExceptionUtil.throwAppException(e);
		}
		return name;
	}
	
	/**
	 * 将Map中的值移植到Bean
	 * 方法功能描述：
	 * 
	 * @param bean
	 * @param properties
	 * @return
	 */
	public static void populate(Object bean, Map<String, Object> properties) {
		try {
			BeanUtilsBean.getInstance().populate(bean, properties);;
		} catch (Exception e) {
			ExceptionUtil.throwAppException(e);
		}
	}
	
	/**
	 * 将Bean中的值移植到Map
	 * 方法功能描述：
	 * 
	 * @param bean
	 * @return
	 */
	public static Map<String, Object> describe(Object bean) {
		try {
			return PropertyUtils.describe(bean);
		} catch (Exception e) {
			ExceptionUtil.throwAppException(e);
		}
		return null;
	}

	/**
	 * 判断class是否包含某属性
	 * @param objClass
	 * @param fieldName
	 * @return
	 */
	public static boolean isContainField(Class<? extends Object> objClass, String fieldName) {
		Field[] fields = objClass.getDeclaredFields();
		for (Field field : fields) {
			if (fieldName.equals(field.getName())) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean isContainAndEmptyField(Object obj, String fieldName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		return isContainField(obj.getClass(), fieldName) && StringUtils.isEmpty(BeanUtils.getProperty(obj, fieldName));
	}

	public static void setProperty(final Object bean, final String name, final Object value) throws InvocationTargetException, IllegalAccessException {
		BeanUtils.setProperty(bean,name,value);
	}

	public static String getFieldValue(Object bean, String fieldName) {
		try {
			return BeanUtils.getProperty(bean, fieldName);
		} catch (Exception e) {
			return "";
		}
	}


}
